package studia.figlewicz.math.library;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

public class Kalendarz {
	
	private final Date today;

	private ArrayList<Date> dniDodatkowoWolne = new ArrayList<Date>();
	private ArrayList<Date> dniDodatkowoPracujace = new ArrayList<Date>();
	private Calendar kalendarz = Calendar.getInstance();
	private boolean niedziela = false;
	private boolean poniedzialek = false;
	private boolean wtorek = false;
	private boolean sroda = false;
	private boolean czwartek = false;
	private boolean piatek = false;
	private boolean sobota = false;
	

	
	// konstruktory
	public Kalendarz(Date today) {
		this.today = (Date)today.clone();
		this.initialize();
	}
	
	
	// gettery i settery
	public Date getToday() {
		return today;
	}
	public ArrayList<Date> getDniDodatkowoWolne() {
		return dniDodatkowoWolne;
	}
	public void setDniDodatkowoWolne(ArrayList<Date> dniDodatkowoWolne) {
		this.dniDodatkowoWolne = dniDodatkowoWolne;
	}
	public ArrayList<Date> getDniDodatkowoPracujace() {
		return dniDodatkowoPracujace;
	}
	public void setDniDodatkowoPracujace(ArrayList<Date> dniDodatkowoPracujace) {
		this.dniDodatkowoPracujace = dniDodatkowoPracujace;
	}
	public void setDzienPracujacy(int dzienTygodnia) {
		if (dzienTygodnia == kalendarz.SUNDAY)
			niedziela = true;
		else if (dzienTygodnia == kalendarz.MONDAY)
			poniedzialek = true;
		else if (dzienTygodnia == kalendarz.TUESDAY)
			wtorek = true;
		else if (dzienTygodnia == kalendarz.WEDNESDAY)
			sroda = true;
		else if (dzienTygodnia == kalendarz.THURSDAY)
			czwartek = true;
		else if (dzienTygodnia == kalendarz.FRIDAY)
			piatek = true;
		else if (dzienTygodnia == kalendarz.SATURDAY)
			sobota = true;
	}
	public boolean isDzienPracujacy(int dzienTygodnia) {
		if (dzienTygodnia == kalendarz.SUNDAY)
			return niedziela;
		else if (dzienTygodnia == kalendarz.MONDAY)
			return poniedzialek;
		else if (dzienTygodnia == kalendarz.TUESDAY)
			return wtorek;
		else if (dzienTygodnia == kalendarz.WEDNESDAY)
			return sroda;
		else if (dzienTygodnia == kalendarz.THURSDAY)
			return czwartek;
		else if (dzienTygodnia == kalendarz.FRIDAY)
			return piatek;
		else if (dzienTygodnia == kalendarz.SATURDAY)
			return sobota;
		return false;
	}
	
	
	// metody dla Date
	public boolean dodajWolny(Date item) {
		return dniDodatkowoWolne.add(item);
	}
	
	public boolean dodajPracujacy(Date item) {
		return dniDodatkowoPracujace.add(item);
	}
	
	public Date getDate(Date data, int lata, int miesiace, int tygodnie, int dni) {
		Date stary = new Date();
		stary = kalendarz.getTime();
		
		kalendarz.setTime(data);
		kalendarz.add(Calendar.YEAR, lata);
		kalendarz.add(Calendar.MONTH, miesiace);
		kalendarz.add(Calendar.WEEK_OF_YEAR, tygodnie);
		kalendarz.add(Calendar.DAY_OF_YEAR, dni);
		Date nowy = new Date();
		nowy = kalendarz.getTime();
		
		kalendarz.setTime(stary);
		
		return nowy;
	}
	
	public Date getDate(Date data, Termin termin) {
		return getDate(data, termin.lata, termin.miesiace, termin.tygodnie, termin.dni);
	}
	
	public Date nastepnyPracujacy(Date dzien) {
		kalendarz.setTime(dzien);
		
		do {
			kalendarz.add(Calendar.DAY_OF_MONTH,1);
		} while (czyPracujacy(kalendarz.getTime()));
		
		return kalendarz.getTime();
	}
	
	public Date poprzedniPracujacy(Date dzien) {
		kalendarz.setTime(dzien);
		
		do {
			kalendarz.add(Calendar.DAY_OF_MONTH,-1);
		} while (czyPracujacy(kalendarz.getTime()));
		
		return kalendarz.getTime();
	}

	public boolean czyPracujacy(Date dzien) {
		if (czyStandardowoPracujacy(dzien))
			return true;
		if (czyDodatkowoPracujacy(dzien))
			return true;
		return false;
	}
	
	public boolean czyWolny(Date dzien) {
		if (czyStandardowoPracujacy(dzien))
			return true;
		if (czyDodatkowoWolny(dzien))
			return true;
		return false;
	}

	public Termin nastepnyPracujacy(Termin dzien) {
		Date pracujacy = nastepnyPracujacy(dzien.getData());
		return new Termin(pracujacy);
	}
	
	public Termin poprzedniPracujacy(Termin dzien) {
		Date pracujacy = poprzedniPracujacy(dzien.getData());
		return new Termin(pracujacy);
	}

	public boolean czyPracujacy(Termin dzien) {
		return czyPracujacy(dzien.getData());
	}
	
	public boolean czyWolny(Termin dzien) {
		return czyWolny(dzien.getData());
	}
	
	
	// motody prywatne
	private boolean czyDodatkowoPracujacy(Date dzien) {
		for (Date pracujacy : dniDodatkowoPracujace) {
			if (czyTenSamDzien(pracujacy,dzien))
				return true;
		}
		return false;
	}
	
	private boolean czyDodatkowoWolny(Date dzien) {
		for (Date wolny : dniDodatkowoWolne) {
			if (czyTenSamDzien(wolny,dzien))
				return true;
		}
		return false;
	}
	
	private boolean czyStandardowoPracujacy(Date dzien) {
		Calendar kal = Calendar.getInstance();
		kal.setFirstDayOfWeek(kalendarz.getFirstDayOfWeek());
		kal.setTime(dzien);
		int dzienTygodnia = kal.DAY_OF_WEEK;
		boolean wynik = !isDzienPracujacy(dzienTygodnia);
		return wynik;
	}
	
	private boolean czyStandardowoWony(Date dzien) {
		return !czyStandardowoPracujacy(dzien);
	}
	
	private void initialize() {
		kalendarz.setLenient(true);
		kalendarz.setFirstDayOfWeek(Calendar.MONDAY);
		kalendarz.setTime(this.today);
	}
	
	private boolean czyTenSamDzien (Date d1, Date d2) {
		if (d1.getYear()!=d2.getYear())
			return false;
		else if  (d1.getMonth()!=d2.getMonth())
			return false;
		else if  (d1.getDate()!=d2.getDate())
			return false;
		return true;
	}


}
